/**
 * 命令模式的意图是把请求封装为对象, 从而分离请求的发起者和请求的接收者(执行者)之间的耦合关系.
 * 在命令被执行之前,可以预先王命令对象中植入命令的接收者.
 *  */

// 在面向对象版本的命令模式中,预先植入的命令接收者被当成对象的属性保存起来;
var TV = {
    open: function () {
        console.log('打开电视');
    },
    close: function () {
        console.log('关闭电视');
    }
};
var OpenTvCommand = function (receiver) {
    this.receiver = receiver;
};
OpenTvCommand.prototype.execute = function () {
    this.receiver.open(); // 执行命令,打开电视机
};
OpenTvCommand.prototype.undo = function () {
    this.receiver.close(); // 撤销命令,关闭电视机
};

var setCommand = function (command) {
    document.getElementById('execute').onclick = function () {
        command.execute();
    }
    document.getElementById('undo').onclick = function () {
        command.undo();
    }
};
setCommand(new OpenTvCommand(Tv));

// 而在闭包的命令模式中,命令接收者会被封闭在闭包形成的环境中.
var createCommand = function (receiver) {
    var execute = function () {
        return receiver.open();
    }
    var undow = function () {
        return receiver.close();
    }
    return {
        execute: execute,
        undo: undo
    }
}
var setCommand = function (command) {
    document.getElementById('execute').onclick = function () {
        command.execute();
    }
    document.getElementById('undo').onclick = function () {
        command.undo();
    }
};
setCommand(createCommand(Tv));